namespace GemBox.Spreadsheet
{
    using System;
    using System.Collections;
    using System.Drawing;
    using System.Globalization;
    using System.IO;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Xml;

    internal class XlsxWriteDirector : XlsxDirector
    {
        private IndexedHashCollection borders;
        private ArrayList cellStyles;
        private ArrayList commentAuthorList;
        private Stream commentShapeContentStream;
        private IndexedHashCollection fillPatterns;
        private IndexedHashCollection fonts;
        private NumberFormatCollection numberFormats;
        private Random random;
        private Hashtable sourceParts;
        private IndexedHashCollection strings;
        private string vmlDrawingBeginingContent;

        public XlsxWriteDirector(PackageBuilderBase builder, ExcelFile excelFile) : base(builder, excelFile)
        {
            this.strings = new IndexedHashCollection();
            this.cellStyles = new ArrayList();
            this.fonts = new IndexedHashCollection();
            this.numberFormats = new NumberFormatCollection(false);
            this.fillPatterns = new IndexedHashCollection();
            this.borders = new IndexedHashCollection();
            this.commentAuthorList = new ArrayList();
            this.random = new Random();
            excelFile.CellStyleCache.EmptyAddQueue();
            CellStyleData element = new CellStyleData(excelFile.CellStyleCache, false, excelFile.DefaultFontName, excelFile.DefaultFontSize);
            this.CreateCellStyleIndexes(element);
            this.fillPatterns.Add(new FillPatternData(FillPatternStyle.Gray12, Color.Black, Color.White));
            Assembly executingAssembly = Assembly.GetExecutingAssembly();
            this.vmlDrawingBeginingContent = new StreamReader(executingAssembly.GetManifestResourceStream("GemBox.Spreadsheet.OpenXml.DrawingParts.VmlDrawingBegining.txt")).ReadToEnd();
            this.commentShapeContentStream = executingAssembly.GetManifestResourceStream("GemBox.Spreadsheet.OpenXml.DrawingParts.VmlDrawingShape.txt");
        }

        private void AddToWorkbookXml(ExcelWorksheetCollection sheets, string[] rids)
        {
            string workbookContentType;
            string path = "/xl/workbook.xml";
            Stream part = base.excelFile.preservedXlsx.GetPart(path);
            XlsxExcelFilePreservationData tag = base.excelFile.Tag as XlsxExcelFilePreservationData;
            if ((tag != null) && (tag.WorkbookContentType != null))
            {
                workbookContentType = tag.WorkbookContentType;
            }
            else
            {
                workbookContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";
            }
            Stream w = base.builder.CreatePart(path, workbookContentType);
            this.sourceParts.Remove(path);
            XmlTextReader reader = new XmlTextReader(part);
            try
            {
                XmlTextWriter writer = new XmlTextWriter(w, new UTF8Encoding(false));
                try
                {
                    while (reader.Read())
                    {
                        if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "sheets"))
                        {
                            WriteSheetsCollectionToWorkbook(sheets, rids, reader, writer);
                        }
                        else
                        {
                            if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "workbookView"))
                            {
                                writer.WriteStartElement("workbookView");
                                writer.WriteAttributeString("activeTab", sheets.GetActiveWorksheetIndex().ToString());
                                writer.WriteEndElement();
                                continue;
                            }
                            if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "definedNames"))
                            {
                                WriteDefinedNamesPart(sheets, reader, writer);
                                continue;
                            }
                            WriteShallowNode(reader, writer);
                        }
                    }
                }
                finally
                {
                    writer.Close();
                }
            }
            finally
            {
                reader.Close();
            }
        }

        private static string ColorToRgbString(Color color)
        {
            return color.ToArgb().ToString("X6");
        }

        public override void Construct()
        {
            this.sourceParts = base.excelFile.preservedXlsx.Parts;
            this.WriteWorksheets();
            this.WriteSharedStrings();
            this.WriteStyles();
            this.CopyTemplate();
        }

        private void CopyTemplate()
        {
            foreach (DictionaryEntry entry in this.sourceParts)
            {
                string key = (string) entry.Key;
                string contentType = (string) entry.Value;
                using (Stream stream = base.excelFile.preservedXlsx.GetPart(key))
                {
                    using (Stream stream2 = base.builder.CreatePart(key, contentType))
                    {
                        Utilities.CopyStream(stream, stream2);
                    }
                    continue;
                }
            }
        }

        private void CreateCellArguments(object val, out string typeStr, out string strVal)
        {
            typeStr = null;
            switch (val.GetType().FullName)
            {
                case "System.Byte":
                case "System.SByte":
                case "System.Int16":
                case "System.UInt16":
                case "System.UInt32":
                case "System.Int32":
                    strVal = val.ToString();
                    return;

                case "System.Single":
                    strVal = ((float) val).ToString(CultureInfo.InvariantCulture);
                    return;

                case "System.Double":
                    break;

                case "System.Decimal":
                    strVal = ((decimal) val).ToString(CultureInfo.InvariantCulture);
                    return;

                case "System.Boolean":
                    typeStr = "b";
                    if ((bool) val)
                    {
                        strVal = "1";
                        return;
                    }
                    strVal = "0";
                    return;

                case "System.String":
                    goto Label_0181;

                case "System.DateTime":
                    val = XLSFileWriter.GetEncodedDateTime((DateTime) val, base.excelFile.Use1904DateSystem);
                    break;

                default:
                    val = val.ToString();
                    goto Label_0181;
            }
            strVal = ((double) val).ToString("G17", CultureInfo.InvariantCulture);
            return;
        Label_0181:
            typeStr = "s";
            strVal = this.strings.Add((string) val).ToString();
        }

        private void CreateCellStyleIndexes(CellStyleData element)
        {
            CellStyleDataIndexes indexes = new CellStyleDataIndexes();
            indexes.CellStyleIndex = this.cellStyles.Add(element);
            indexes.FontIndex = this.fonts.Add(element.FontData);
            if (element.NumberFormat.Length == 0)
            {
                indexes.NumberFormatIndex = 0;
            }
            else
            {
                indexes.NumberFormatIndex = this.numberFormats.Add(element.NumberFormat);
            }
            FillPatternData data = new FillPatternData(element.PatternStyle, element.PatternForegroundColor, element.PatternBackgroundColor);
            indexes.FillPatternIndex = this.fillPatterns.Add(data);
            BordersData data2 = new BordersData(element.BorderColor, element.BorderStyle, element.BordersUsed);
            indexes.BordersIndex = this.borders.Add(data2);
            element.Indexes = indexes;
        }

        private static string FillPatternToString(FillPatternStyle fillPattern)
        {
            int num = (int) fillPattern;
            XlsxFillStyle style = (XlsxFillStyle) num;
            return style.ToString();
        }

        private static string FirstCharToLower(string str)
        {
            char[] chArray = str.ToCharArray();
            chArray[0] = char.ToLower(chArray[0]);
            return new string(chArray);
        }

        private int GetCellStyleIndex(CellStyle cellStyle)
        {
            CellStyleData element = cellStyle.Element;
            if (element.Indexes == null)
            {
                this.CreateCellStyleIndexes(element);
            }
            return element.Indexes.CellStyleIndex;
        }

        private string GetFreeFileName(string directory, string prefix, string extension)
        {
            string key = null;
            extension = extension.ToLower();
            for (int i = 0; i < 0x3e8; i++)
            {
                key = Path.Combine(directory, prefix + this.random.Next(0x2710).ToString() + "." + extension);
                if (!this.sourceParts.Contains(key) && !base.builder.Parts.Contains(key))
                {
                    return key;
                }
            }
            throw new SpreadsheetException("Internal: FileName could not be assigned!");
        }

        private XmlTextWriter GetVmlDrawingWriter(string vmlDrawingPath)
        {
            Path.GetFileName(vmlDrawingPath);
            return new XmlTextWriter(base.builder.CreatePart(vmlDrawingPath, "application/vnd.openxmlformats-officedocument.vmlDrawing"), new UTF8Encoding(false));
        }

        private void RemoveContentTypeFromTemplate(string removeContentType, bool matchWholeContentTypeString)
        {
            Hashtable hashtable = new Hashtable();
            foreach (DictionaryEntry entry in this.sourceParts)
            {
                string key = (string) entry.Key;
                string str2 = (string) entry.Value;
                if ((str2 != removeContentType) && (matchWholeContentTypeString || !str2.StartsWith(removeContentType)))
                {
                    hashtable.Add(key, str2);
                }
            }
            this.sourceParts = hashtable;
        }

        private void WriteAnchorCell(AnchorCell cell, XmlTextWriter writer)
        {
            writer.WriteStartElement("xdr:col");
            writer.WriteString(cell.Column.Index.ToString());
            writer.WriteEndElement();
            writer.WriteStartElement("xdr:colOff");
            writer.WriteString(cell.ColumnOffset.ToString());
            writer.WriteEndElement();
            writer.WriteStartElement("xdr:row");
            writer.WriteString(cell.Row.Index.ToString());
            writer.WriteEndElement();
            writer.WriteStartElement("xdr:rowOff");
            writer.WriteString(cell.RowOffset.ToString());
            writer.WriteEndElement();
        }

        private void WriteAnchorToVmlDrawing(XmlTextWriter writer, CommentShape shape)
        {
            if (!shape.anchorSet)
            {
                shape.LeftOffset = 15;
                shape.TopOffset = 10;
                shape.RightOffset = 15;
                shape.BottomOffset = 4;
                if (shape.Column < 0x4000)
                {
                    shape.Left = shape.Column + 1;
                }
                else
                {
                    shape.Left = 0x4000;
                }
                if (shape.Left <= 0x3ffe)
                {
                    shape.Right = shape.Left + 2;
                }
                else
                {
                    shape.Right = 0x4000;
                }
                if (shape.Row > 0)
                {
                    shape.Top = shape.Row - 1;
                }
                else
                {
                    shape.Top = 0;
                }
                if (shape.Top <= 0xffffc)
                {
                    shape.Bottom = shape.Top + 4;
                }
                else
                {
                    shape.Bottom = 0x100000;
                }
            }
            string text = shape.Left.ToString() + ", " + shape.LeftOffset.ToString() + ", " + shape.Top.ToString() + ", " + shape.TopOffset.ToString() + ", " + shape.Right.ToString() + ", " + shape.RightOffset.ToString() + ", " + shape.Bottom.ToString() + ", " + shape.BottomOffset.ToString();
            writer.WriteStartElement("x:Anchor");
            writer.WriteString(text);
            writer.WriteEndElement();
        }

        private void WriteAutoFilterIfNeeded(XlsxSheetPreservationData tagData, XmlTextWriter writer)
        {
            if (tagData != null)
            {
                Utilities.WriteRawDataIfNeeded(tagData.AutoFilterOuterString, writer);
            }
        }

        private void WriteBorder(XmlTextWriter writer, string name, LineStyle style, Color color)
        {
            writer.WriteStartElement(name);
            writer.WriteAttributeString("style", FirstCharToLower(style.ToString()));
            this.WriteColorElement(writer, "color", color, Color.Black);
            writer.WriteEndElement();
        }

        private void WriteBorders(XmlTextWriter writer)
        {
            writer.WriteStartElement("borders");
            writer.WriteAttributeString("count", this.borders.Count.ToString());
            foreach (BordersData data in this.borders)
            {
                writer.WriteStartElement("border");
                if ((data.BordersUsed & MultipleBorders.DiagonalUp) != MultipleBorders.None)
                {
                    writer.WriteAttributeString("diagonalUp", "1");
                }
                if ((data.BordersUsed & MultipleBorders.DiagonalDown) != MultipleBorders.None)
                {
                    writer.WriteAttributeString("diagonalDown", "1");
                }
                for (int i = 0; i < 4; i++)
                {
                    int index = (i + 2) % 4;
                    IndividualBorder individualBorder = (IndividualBorder) index;
                    if ((data.BordersUsed & CellBorder.MultipleFromIndividualBorder(individualBorder)) != MultipleBorders.None)
                    {
                        this.WriteBorder(writer, individualBorder.ToString().ToLower(), data.BorderStyle[index], data.BorderColor[index]);
                    }
                }
                if ((data.BordersUsed & MultipleBorders.Diagonal) != MultipleBorders.None)
                {
                    this.WriteBorder(writer, "diagonal", data.BorderStyle[4], data.BorderColor[4]);
                }
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }

        private void WriteCellIfNeeded(ExcelCell cell, int row, int column, XmlTextWriter writer)
        {
            object obj2;
            CellStyle style;
            string formula;
            MergedCellRange mergedRange = (MergedCellRange) cell.MergedRange;
            if (mergedRange != null)
            {
                if ((row == mergedRange.FirstRowIndex) && (column == mergedRange.FirstColumnIndex))
                {
                    obj2 = mergedRange.Value;
                    formula = mergedRange.Formula;
                }
                else
                {
                    obj2 = null;
                    formula = null;
                }
                style = mergedRange.StyleResolved(row, column);
            }
            else
            {
                obj2 = cell.Value;
                if (cell.IsStyleDefault)
                {
                    style = null;
                }
                else
                {
                    style = cell.Style;
                }
                formula = cell.Formula;
            }
            if (((style != null) || (obj2 != null)) || (formula != null))
            {
                XLSFileWriter.SetDefaultDateFormatIfNeeded(obj2, ref style, base.excelFile);
                writer.WriteStartElement("c");
                writer.WriteAttributeString("r", CellRange.RowColumnToPosition(row, column));
                if (style != null)
                {
                    this.WriteCellStyle(style, writer);
                }
                string strVal = null;
                if (obj2 != null)
                {
                    string str3;
                    this.CreateCellArguments(obj2, out str3, out strVal);
                    if (str3 != null)
                    {
                        writer.WriteAttributeString("t", str3);
                    }
                }
                if (formula != null)
                {
                    this.WriteFormula(cell.FormulaInternal, writer);
                }
                if (strVal != null)
                {
                    writer.WriteElementString("v", strVal);
                }
                writer.WriteEndElement();
            }
        }

        private void WriteCellStyle(CellStyle cellStyle, XmlTextWriter writer)
        {
            writer.WriteAttributeString("s", this.GetCellStyleIndex(cellStyle).ToString());
        }

        private void WriteCellStyles(XmlTextWriter writer)
        {
            writer.WriteStartElement("cellStyles");
            writer.WriteAttributeString("count", "1");
            writer.WriteStartElement("cellStyle");
            writer.WriteAttributeString("name", "Normal");
            writer.WriteAttributeString("xfId", "0");
            writer.WriteAttributeString("builtinId", "0");
            writer.WriteEndElement();
            writer.WriteEndElement();
        }

        private void WriteCellStyleXfs(XmlTextWriter writer)
        {
            writer.WriteStartElement("cellStyleXfs");
            writer.WriteAttributeString("count", "1");
            this.WriteEmptyXfElement(writer);
            writer.WriteEndElement();
        }

        private void WriteCellXfs(XmlTextWriter writer)
        {
            writer.WriteStartElement("cellXfs");
            writer.WriteAttributeString("count", this.cellStyles.Count.ToString());
            foreach (CellStyleData data in this.cellStyles)
            {
                this.WriteComplexXfElement(writer, data);
                data.Indexes = null;
            }
            writer.WriteEndElement();
        }

        private void WriteColorElement(XmlTextWriter writer, string elementName, Color color, Color defaultColor)
        {
            if (color.ToArgb() != defaultColor.ToArgb())
            {
                writer.WriteStartElement(elementName);
                writer.WriteAttributeString("rgb", ColorToRgbString(color));
                writer.WriteEndElement();
            }
        }

        private void WriteColumnInfosIfNeeded(ExcelWorksheet ws, XmlTextWriter writer)
        {
            int count = ws.Columns.Count;
            ArrayList list = new ArrayList();
            for (int i = 0; i < count; i++)
            {
                ExcelColumn column = ws.Columns[i];
                if (((column.Width != ws.DefaultColumnWidth) || (column.OutlineLevel > 0)) || (column.Collapsed || column.Hidden))
                {
                    list.Add(i);
                }
            }
            if (list.Count > 0)
            {
                writer.WriteStartElement("cols");
                foreach (int num3 in list)
                {
                    ExcelColumn item = ws.Columns[num3];
                    writer.WriteStartElement("col");
                    string str = (num3 + 1).ToString();
                    writer.WriteAttributeString("min", str);
                    writer.WriteAttributeString("max", str);
                    writer.WriteAttributeString("width", (((float) item.Width) / 256f).ToString(CultureInfo.InvariantCulture));
                    writer.WriteAttributeString("customWidth", "1");
                    WriteHiddenOutlineCollapsedIfNeeded(writer, item, ws.ViewOptions, ws.Columns.MaxOutlineLevel);
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
            }
        }

        private void WriteCommentAuthorList(XmlTextWriter writer)
        {
            writer.WriteStartElement("authors");
            foreach (string str in this.commentAuthorList)
            {
                writer.WriteStartElement("author");
                writer.WriteString(str);
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }

        private void WriteCommentsAndTemplateShapesIfNeeded(ExcelWorksheet ws, string vmlDrawingPath, string commentPartPath)
        {
            XmlTextWriter vmlDrawingWriter = null;
            XmlTextWriter writer2 = null;
            int commentShapeIndex = 0;
            XlsxSheetPreservationData tag = ws.Tag as XlsxSheetPreservationData;
            SpreadsheetRelationshipCollection relationships = new SpreadsheetRelationshipCollection();
            try
            {
                foreach (ExcelShape shape in ws.Shapes)
                {
                    if (shape is CommentShape)
                    {
                        if (vmlDrawingWriter == null)
                        {
                            Stream w = base.builder.CreatePart(commentPartPath, "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml");
                            vmlDrawingWriter = this.GetVmlDrawingWriter(vmlDrawingPath);
                            this.WriteLegacyDrawingStartElement(vmlDrawingWriter);
                            this.WriteLegacyDrawingShapeLayout(vmlDrawingWriter);
                            this.WriteVmlDrawingCommentBegining(vmlDrawingWriter);
                            writer2 = new XmlTextWriter(w, new UTF8Encoding(false));
                            writer2.WriteStartDocument(true);
                            writer2.WriteStartElement("comments");
                            writer2.WriteAttributeString("xmlns", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
                            this.WriteCommentAuthorList(writer2);
                            writer2.WriteStartElement("commentList");
                        }
                        commentShapeIndex++;
                        this.WriteCommentShape(vmlDrawingWriter, (CommentShape) shape, commentShapeIndex);
                        this.WriteCommentTag(writer2, (CommentShape) shape, commentShapeIndex);
                    }
                }
                if ((tag != null) && (tag.LegacyDrawingPath != null))
                {
                    if (tag != null)
                    {
                        relationships.LoadRels(tag.LegacyDrawingPath, base.excelFile.preservedXlsx);
                    }
                    if (vmlDrawingWriter == null)
                    {
                        vmlDrawingWriter = this.GetVmlDrawingWriter(vmlDrawingPath);
                        this.WriteLegacyDrawingStartElement(vmlDrawingWriter);
                        this.WriteLegacyDrawingShapeLayout(vmlDrawingWriter);
                    }
                    this.WriteLegacyDrawingPartsFromTemplate(tag, vmlDrawingWriter, vmlDrawingPath);
                }
                if (vmlDrawingWriter != null)
                {
                    vmlDrawingWriter.WriteEndElement();
                }
                if (writer2 != null)
                {
                    writer2.WriteEndElement();
                    writer2.WriteEndElement();
                }
                foreach (string str in relationships.GetVisiblePathsCollection("http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"))
                {
                    string path = Path.Combine("/xl/media/", Path.GetFileName(str));
                    Path.GetExtension(path).ToLower();
                    Stream destination = base.builder.CreatePart(path, (string) this.sourceParts[path]);
                    Utilities.CopyStream(base.excelFile.preservedXlsx.GetPart(path), destination);
                    destination.Close();
                }
                relationships.SaveRels(vmlDrawingPath, base.builder);
            }
            finally
            {
                if (vmlDrawingWriter != null)
                {
                    vmlDrawingWriter.Close();
                }
                if (writer2 != null)
                {
                    writer2.Close();
                }
            }
        }

        private void WriteCommentShape(XmlTextWriter writer, CommentShape shape, int commentShapeIndex)
        {
            this.commentShapeContentStream.Seek(0L, SeekOrigin.Begin);
            XmlTextReader reader = new XmlTextReader(this.commentShapeContentStream);
            while (reader.Read())
            {
                if (reader.Name != "xml")
                {
                    if ((reader.Name == "v:shape") && (reader.NodeType == XmlNodeType.Element))
                    {
                        writer.WriteStartElement("v:shape");
                        writer.WriteAttributeString("id", reader.GetAttribute("id") + commentShapeIndex.ToString());
                        writer.WriteAttributeString("type", reader.GetAttribute("type"));
                        string attribute = reader.GetAttribute("style");
                        if (shape.IsVisible)
                        {
                            attribute = attribute.Replace("hidden", "visible");
                        }
                        writer.WriteAttributeString("style", attribute);
                        writer.WriteAttributeString("fillcolor", reader.GetAttribute("fillcolor"));
                        writer.WriteAttributeString("o:insetmode", reader.GetAttribute("o:insetmode"));
                    }
                    else
                    {
                        if ((reader.Name == "x:Row") || (reader.Name == "x:Column"))
                        {
                            int row;
                            if (reader.Name == "x:Row")
                            {
                                row = shape.Row;
                            }
                            else
                            {
                                row = shape.Column;
                            }
                            this.WriteRowColumnToVmlDrawing(writer, row, reader.Name);
                            reader.Read();
                            reader.Read();
                            continue;
                        }
                        if ((reader.Name == "x:AutoFill") && (reader.NodeType == XmlNodeType.Element))
                        {
                            this.WriteAnchorToVmlDrawing(writer, shape);
                            WriteShallowNode(reader, writer);
                        }
                        else
                        {
                            if (reader.Name == "x:ClientData")
                            {
                                if (shape.IsVisible)
                                {
                                    writer.WriteStartElement("x:Visible");
                                    writer.WriteEndElement();
                                }
                                WriteShallowNode(reader, writer);
                                continue;
                            }
                            WriteShallowNode(reader, writer);
                        }
                    }
                }
            }
        }

        private void WriteCommentTag(XmlTextWriter writer, CommentShape shape, int commentShapeIndex)
        {
            writer.WriteStartElement("comment");
            writer.WriteAttributeString("ref", CellRange.RowColumnToPosition(shape.Row, shape.Column));
            writer.WriteAttributeString("authorId", this.commentAuthorList.IndexOf(shape.Author).ToString());
            writer.WriteStartElement("text");
            writer.WriteStartElement("r");
            writer.WriteStartElement("t");
            writer.WriteString(shape.Text);
            writer.WriteEndElement();
            writer.WriteEndElement();
            writer.WriteEndElement();
            writer.WriteEndElement();
        }

        private void WriteComplexXfElement(XmlTextWriter writer, CellStyleData csData)
        {
            CellStyleDataIndexes indexes = csData.Indexes;
            writer.WriteStartElement("xf");
            writer.WriteAttributeString("numFmtId", indexes.NumberFormatIndex.ToString());
            writer.WriteAttributeString("fontId", indexes.FontIndex.ToString());
            writer.WriteAttributeString("fillId", indexes.FillPatternIndex.ToString());
            writer.WriteAttributeString("borderId", indexes.BordersIndex.ToString());
            if (indexes.NumberFormatIndex > 0)
            {
                writer.WriteAttributeString("applyNumberFormat", "1");
            }
            if (indexes.FontIndex > 0)
            {
                writer.WriteAttributeString("applyFont", "1");
            }
            if (indexes.FillPatternIndex > 0)
            {
                writer.WriteAttributeString("applyFill", "1");
            }
            if (indexes.BordersIndex > 0)
            {
                writer.WriteAttributeString("applyBorder", "1");
            }
            if ((((csData.HorizontalAlignment != HorizontalAlignmentStyle.General) || (csData.VerticalAlignment != VerticalAlignmentStyle.Bottom)) || ((csData.Indent != 0) || (csData.Rotation != 0))) || (csData.WrapText || csData.ShrinkToFit))
            {
                writer.WriteAttributeString("applyAlignment", "1");
                writer.WriteStartElement("alignment");
                if (csData.HorizontalAlignment != HorizontalAlignmentStyle.General)
                {
                    string str = FirstCharToLower(csData.HorizontalAlignment.ToString());
                    if (str == "centerAcross")
                    {
                        str = "centerContinuous";
                    }
                    writer.WriteAttributeString("horizontal", str);
                }
                if (csData.VerticalAlignment != VerticalAlignmentStyle.Bottom)
                {
                    writer.WriteAttributeString("vertical", FirstCharToLower(csData.VerticalAlignment.ToString()));
                }
                if (csData.Indent != 0)
                {
                    writer.WriteAttributeString("indent", csData.Indent.ToString());
                }
                if (csData.Rotation != 0)
                {
                    int num = csData.Rotation % 0x100;
                    if (num < 0)
                    {
                        num += 0x100;
                    }
                    writer.WriteAttributeString("textRotation", num.ToString());
                }
                if (csData.WrapText)
                {
                    writer.WriteAttributeString("wrapText", "1");
                }
                if (csData.ShrinkToFit)
                {
                    writer.WriteAttributeString("shrinkToFit", "1");
                }
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }

        private void WriteConditionalFormattingIfNeeded(XlsxSheetPreservationData tagData, XmlTextWriter writer)
        {
            if (tagData != null)
            {
                Utilities.WriteRawDataIfNeeded(tagData.ConditionalFormattingOuterString, writer);
            }
        }

        private void WriteDataValidationIfNeeded(XlsxSheetPreservationData tagData, XmlTextWriter writer)
        {
            if (tagData != null)
            {
                Utilities.WriteRawDataIfNeeded(tagData.DataValidationOuterString, writer);
            }
        }

        private static void WriteDefinedNamesPart(ExcelWorksheetCollection sheets, XmlTextReader reader, XmlTextWriter writer)
        {
            while (reader.Read())
            {
                if ((reader.NodeType == XmlNodeType.EndElement) && (reader.Name == "definedNames"))
                {
                    break;
                }
            }
            writer.WriteStartElement("definedNames");
            foreach (ExcelWorksheet worksheet in sheets)
            {
                foreach (NamedRange range in worksheet.NamedRanges)
                {
                    string text = "'" + range.Range.Parent.Name.Replace("'", "''") + "'!$" + ExcelColumnCollection.ColumnIndexToName(range.Range.FirstColumnIndex) + "$" + ExcelRowCollection.RowIndexToName(range.Range.FirstRowIndex) + ":$" + ExcelColumnCollection.ColumnIndexToName(range.Range.LastColumnIndex) + "$" + ExcelRowCollection.RowIndexToName(range.Range.LastRowIndex);
                    writer.WriteStartElement("definedName");
                    writer.WriteAttributeString("name", range.Name);
                    if (!range.GlobalName)
                    {
                        writer.WriteAttributeString("localSheetId", sheets.IndexOf(worksheet).ToString());
                    }
                    writer.WriteString(text);
                    writer.WriteEndElement();
                }
            }
            writer.WriteEndElement();
        }

        private void WriteDrawing(ExcelWorksheet ws, string drawingPath)
        {
            int num = 2;
            int num2 = 1;
            SpreadsheetRelationshipCollection relationships = new SpreadsheetRelationshipCollection();
            XlsxSheetPreservationData tag = ws.Tag as XlsxSheetPreservationData;
            ExcelPictureCollection pictureCollection = ws.Pictures;
            XmlTextWriter writer = new XmlTextWriter(base.builder.CreatePart(drawingPath, "application/vnd.openxmlformats-officedocument.drawing+xml"), new UTF8Encoding(false));
            try
            {
                writer.WriteStartDocument(true);
                writer.WriteStartElement("xdr:wsDr");
                writer.WriteAttributeString("xmlns:xdr", "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing");
                writer.WriteAttributeString("xmlns:a", "http://schemas.openxmlformats.org/drawingml/2006/main");
                this.WriteDrawingPartsFromTemplate(tag, writer);
                if ((tag != null) && (tag.DrawingPath != null))
                {
                    relationships.LoadRels(tag.DrawingPath, base.excelFile.preservedXlsx);
                    relationships.Remove("http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");
                    this.sourceParts.Remove(tag.DrawingPath);
                    this.sourceParts.Remove(SpreadsheetRelationshipCollection.GetRelationshipPathFromXmlFilePath(tag.DrawingPath));
                }
                foreach (ExcelPicture picture in pictureCollection)
                {
                    PositioningMode positioning = picture.Positioning;
                    string str = "";
                    string target = this.GetFreeFileName("/xl/media/", "GemImage", picture.PictureFormat.ToString());
                    writer.WriteStartElement("xdr:twoCellAnchor");
                    switch (positioning)
                    {
                        case PositioningMode.FreeFloating:
                            str = "absolute";
                            break;

                        case PositioningMode.Move:
                            str = "oneCell";
                            break;

                        case PositioningMode.MoveAndSize:
                            str = "twoCell";
                            break;
                    }
                    writer.WriteAttributeString("editAs", str);
                    writer.WriteStartElement("xdr:from");
                    this.WriteAnchorCell(picture.TopLeftCell, writer);
                    writer.WriteEndElement();
                    writer.WriteStartElement("xdr:to");
                    this.WriteAnchorCell(picture.BottomRightCell, writer);
                    writer.WriteEndElement();
                    writer.WriteStartElement("xdr:pic");
                    writer.WriteStartElement("xdr:nvPicPr");
                    writer.WriteStartElement("xdr:cNvPr");
                    writer.WriteAttributeString("id", num.ToString());
                    writer.WriteAttributeString("name", "Picture " + num2.ToString());
                    writer.WriteEndElement();
                    writer.WriteStartElement("xdr:cNvPicPr");
                    writer.WriteEndElement();
                    writer.WriteEndElement();
                    writer.WriteStartElement("xdr:blipFill");
                    writer.WriteStartElement("a:blip");
                    writer.WriteAttributeString("xmlns:r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
                    writer.WriteAttributeString("r:embed", relationships.Add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", target, null));
                    writer.WriteEndElement();
                    writer.WriteStartElement("a:stretch");
                    writer.WriteStartElement("a:fillRect");
                    writer.WriteEndElement();
                    writer.WriteEndElement();
                    writer.WriteEndElement();
                    writer.WriteStartElement("xdr:spPr");
                    writer.WriteStartElement("a:prstGeom");
                    writer.WriteAttributeString("prst", "rect");
                    writer.WriteEndElement();
                    writer.WriteEndElement();
                    writer.WriteEndElement();
                    writer.WriteStartElement("xdr:clientData");
                    writer.WriteEndElement();
                    writer.WriteEndElement();
                    num2++;
                    num++;
                }
                writer.WriteEndElement();
                relationships.SaveRels(drawingPath, base.builder);
                this.WriteImages(pictureCollection, relationships.GetVisiblePathsCollection("http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"));
            }
            finally
            {
                writer.Close();
            }
        }

        private void WriteDrawingPartsFromTemplate(XlsxSheetPreservationData tagData, XmlTextWriter writer)
        {
            XmlDocument document = new XmlDocument();
            if ((tagData != null) && this.sourceParts.Contains(tagData.DrawingPath))
            {
                document.Load(base.excelFile.preservedXlsx.GetPart(tagData.DrawingPath));
                XmlNode node = document.GetElementsByTagName("xdr:wsDr")[0];
                XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable);
                nsmgr.AddNamespace("xdr", "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing");
                foreach (XmlNode node2 in node.ChildNodes)
                {
                    if (node2.SelectSingleNode("child::xdr:pic", nsmgr) == null)
                    {
                        node2.WriteTo(writer);
                    }
                }
            }
        }

        private void WriteDxfsIfNeeded(XmlTextWriter writer)
        {
            XlsxExcelFilePreservationData tag = base.excelFile.Tag as XlsxExcelFilePreservationData;
            if ((tag != null) && (tag.DxfsStyleOuterString != null))
            {
                Utilities.WriteRawDataIfNeeded(tag.DxfsStyleOuterString, writer);
            }
        }

        private void WriteEmptyXfElement(XmlTextWriter writer)
        {
            writer.WriteStartElement("xf");
            writer.WriteAttributeString("numFmtId", "0");
            writer.WriteAttributeString("fontId", "0");
            writer.WriteAttributeString("fillId", "0");
            writer.WriteAttributeString("borderId", "0");
            writer.WriteEndElement();
        }

        private void WriteFills(XmlTextWriter writer)
        {
            writer.WriteStartElement("fills");
            writer.WriteAttributeString("count", this.fillPatterns.Count.ToString());
            foreach (FillPatternData data in this.fillPatterns)
            {
                writer.WriteStartElement("fill");
                writer.WriteStartElement("patternFill");
                writer.WriteAttributeString("patternType", FillPatternToString(data.PatternStyle));
                if (data.PatternStyle != FillPatternStyle.None)
                {
                    this.WriteColorElement(writer, "fgColor", data.PatternForegroundColor, Color.Black);
                    if (data.PatternStyle != FillPatternStyle.Solid)
                    {
                        this.WriteColorElement(writer, "bgColor", data.PatternBackgroundColor, Color.White);
                    }
                }
                writer.WriteEndElement();
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }

        private void WriteFonts(XmlTextWriter writer)
        {
            writer.WriteStartElement("fonts");
            writer.WriteAttributeString("count", this.fonts.Count.ToString());
            foreach (ExcelFontData data in this.fonts)
            {
                writer.WriteStartElement("font");
                if (data.Weight == 700)
                {
                    writer.WriteStartElement("b");
                    writer.WriteEndElement();
                }
                if (data.Italic)
                {
                    writer.WriteStartElement("i");
                    writer.WriteEndElement();
                }
                if (data.Strikeout)
                {
                    writer.WriteStartElement("strike");
                    writer.WriteEndElement();
                }
                if (data.UnderlineStyle != UnderlineStyle.None)
                {
                    writer.WriteStartElement("u");
                    if (data.UnderlineStyle != UnderlineStyle.Single)
                    {
                        writer.WriteAttributeString("val", FirstCharToLower(data.UnderlineStyle.ToString()));
                    }
                    writer.WriteEndElement();
                }
                if (data.ScriptPosition != ScriptPosition.Normal)
                {
                    writer.WriteStartElement("vertAlign");
                    writer.WriteAttributeString("val", FirstCharToLower(data.ScriptPosition.ToString()));
                    writer.WriteEndElement();
                }
                writer.WriteStartElement("sz");
                writer.WriteAttributeString("val", (((double) data.Size) / 20.0).ToString(CultureInfo.InvariantCulture));
                writer.WriteEndElement();
                this.WriteColorElement(writer, "color", data.Color, Color.Black);
                writer.WriteStartElement("name");
                writer.WriteAttributeString("val", data.Name);
                writer.WriteEndElement();
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }

        private void WriteFormula(CellFormula cellFormula, XmlTextWriter writer)
        {
            string text = cellFormula.Formula.Substring(1);
            writer.WriteStartElement("f");
            writer.WriteAttributeString("ca", "1");
            writer.WriteString(text);
            writer.WriteEndElement();
        }

        private void WriteHeaderFooterIfNeeded(XlsxSheetPreservationData tagData, XmlTextWriter writer)
        {
            if (tagData != null)
            {
                Utilities.WriteRawDataIfNeeded(tagData.HeaderFooterOuterString, writer);
            }
        }

        private static void WriteHiddenOutlineCollapsedIfNeeded(XmlTextWriter writer, ExcelColumnRowBase item, ExcelViewOptions viewOptions, int maxOutlineLevel)
        {
            bool hidden = item.Hidden;
            if (item.OutlineLevel > 0)
            {
                writer.WriteAttributeString("outlineLevel", item.OutlineLevel.ToString());
            }
            if (item.Collapsed)
            {
                writer.WriteAttributeString("collapsed", "1");
                if (viewOptions.ShowOutlineSymbols && (maxOutlineLevel > 0))
                {
                    hidden = true;
                }
            }
            if (hidden)
            {
                writer.WriteAttributeString("hidden", "1");
            }
        }

        private void WriteHyperlinksIfNeeded(SpreadsheetHyperlinkCollection hyperlinkCollection, XmlTextWriter writer, SpreadsheetRelationshipCollection relationshipCollection)
        {
            if (hyperlinkCollection.Count > 0)
            {
                writer.WriteStartElement("hyperlinks");
                foreach (SpreadsheetHyperlink hyperlink in hyperlinkCollection)
                {
                    writer.WriteStartElement("hyperlink");
                    writer.WriteAttributeString("ref", CellRange.RowColumnToPosition(hyperlink.Row, hyperlink.Column));
                    if (!hyperlink.IsExternal)
                    {
                        writer.WriteAttributeString("location", hyperlink.Location);
                    }
                    else
                    {
                        writer.WriteAttributeString("r:id", relationshipCollection.Add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", hyperlink.Location, "External"));
                    }
                    if (hyperlink.ToolTip != string.Empty)
                    {
                        writer.WriteAttributeString("tooltip", hyperlink.ToolTip);
                    }
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
            }
        }

        private void WriteImages(ExcelPictureCollection pictureCollection, ArrayList relPaths)
        {
            for (int i = 0; i < pictureCollection.Count; i++)
            {
                ExcelPicture picture = pictureCollection[i];
                string path = relPaths[i].ToString();
                string extension = Path.GetExtension(path);
                Stream destination = base.builder.CreatePart(path, "image/" + extension.Substring(1));
                picture.ImageStream.Seek(0L, SeekOrigin.Begin);
                Utilities.CopyStream(picture.ImageStream, destination);
                destination.Close();
            }
        }

        private void WriteLegacyDrawingHFIfNeeded(SpreadsheetRelationshipCollection relationshipCollection, XlsxSheetPreservationData tagData, XmlTextWriter writer)
        {
            if (((tagData != null) && (tagData.LegacyDrawingHFPath != null)) && this.sourceParts.Contains(tagData.LegacyDrawingHFPath))
            {
                string path = this.GetFreeFileName("/xl/drawings/", "GemVmlDrawing", "vml");
                Stream destination = base.builder.CreatePart(path, "application/vnd.openxmlformats-officedocument.vmlDrawing");
                SpreadsheetRelationshipCollection relationships = new SpreadsheetRelationshipCollection();
                relationships.LoadRels(tagData.LegacyDrawingHFPath, base.excelFile.preservedXlsx);
                Utilities.CopyStream(base.excelFile.preservedXlsx.GetPart(tagData.LegacyDrawingHFPath), destination);
                destination.Close();
                writer.WriteStartElement("legacyDrawingHF");
                writer.WriteAttributeString("r:id", relationshipCollection.Add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing", path, null));
                writer.WriteEndElement();
                foreach (string str2 in relationships.GetVisiblePathsCollection("http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"))
                {
                    string str3 = Path.Combine("/xl/media/", Path.GetFileName(str2));
                    string str4 = Path.GetExtension(str3).ToLower();
                    Stream stream2 = base.builder.CreatePart(str3, "image/" + str4.Substring(1));
                    Utilities.CopyStream(base.excelFile.preservedXlsx.GetPart(str3), stream2);
                    stream2.Close();
                }
                relationships.SaveRels(path, base.builder);
            }
        }

        private void WriteLegacyDrawingPartsFromTemplate(XlsxSheetPreservationData tagData, XmlTextWriter writer, string vmlDrawingPath)
        {
            XmlDocument document = new XmlDocument();
            if (this.sourceParts.Contains(tagData.LegacyDrawingPath))
            {
                document.Load(base.excelFile.preservedXlsx.GetPart(tagData.LegacyDrawingPath));
                XmlNode node = document.GetElementsByTagName("xml")[0];
                XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable);
                nsmgr.AddNamespace("x", "urn:schemas-microsoft-com:office:excel");
                foreach (XmlNode node2 in node.ChildNodes)
                {
                    if (((node2.Name != "v:shapetype") || (node2.Attributes["id"].Value != "GemComType")) && ((node2.SelectSingleNode("child::x:ClientData[attribute::ObjectType=\"Note\"]", nsmgr) == null) && (node2.Name != "o:shapelayout")))
                    {
                        node2.WriteTo(writer);
                    }
                }
            }
        }

        private void WriteLegacyDrawingShapeLayout(XmlTextWriter writer)
        {
            writer.WriteStartElement("o:shapelayout");
            writer.WriteAttributeString("v:ext", "edit");
            writer.WriteStartElement("o:idmap");
            writer.WriteAttributeString("v:ext", "edit");
            writer.WriteEndElement();
            writer.WriteEndElement();
        }

        private void WriteLegacyDrawingStartElement(XmlTextWriter writer)
        {
            writer.WriteStartElement("xml");
            writer.WriteAttributeString("xmlns:v", "urn:schemas-microsoft-com:vml");
            writer.WriteAttributeString("xmlns:o", "urn:schemas-microsoft-com:office:office");
            writer.WriteAttributeString("xmlns:x", "urn:schemas-microsoft-com:office:excel");
        }

        private void WriteLegacyShapesIfNeeded(ExcelWorksheet ws, SpreadsheetRelationshipCollection relationshipCollection, XmlTextWriter writer)
        {
            string vmlDrawingPath = this.GetFreeFileName("/xl/drawings/", "GemVmlDrawing", "vml");
            string commentPartPath = this.GetFreeFileName("/xl/", "GemComments", "xml");
            this.WriteCommentsAndTemplateShapesIfNeeded(ws, vmlDrawingPath, commentPartPath);
            if (base.builder.Parts.Contains(vmlDrawingPath))
            {
                writer.WriteStartElement("legacyDrawing");
                writer.WriteAttributeString("r:id", relationshipCollection.Add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing", vmlDrawingPath, null));
                writer.WriteEndElement();
            }
            if (base.builder.Parts.Contains(commentPartPath))
            {
                this.commentAuthorList.Clear();
                relationshipCollection.Add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments", commentPartPath, null);
            }
        }

        private static void WriteMergedRangesIfNeeded(ICollection values, XmlTextWriter writer)
        {
            if (values.Count > 0)
            {
                writer.WriteStartElement("mergeCells");
                writer.WriteAttributeString("count", values.Count.ToString());
                foreach (MergedCellRange range in values)
                {
                    string str = range.StartPosition + ":" + range.EndPosition;
                    writer.WriteStartElement("mergeCell");
                    writer.WriteAttributeString("ref", str);
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
            }
        }

        private void WriteNumberFormats(XmlTextWriter writer)
        {
            int num = this.numberFormats.Count - 0xa4;
            if (num > 0)
            {
                writer.WriteStartElement("numFmts");
                writer.WriteAttributeString("count", num.ToString());
                for (int i = 0xa4; i < this.numberFormats.Count; i++)
                {
                    string str = (string) this.numberFormats[i];
                    writer.WriteStartElement("numFmt");
                    writer.WriteAttributeString("numFmtId", i.ToString());
                    writer.WriteAttributeString("formatCode", str);
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
            }
        }

        private void WritePageBreaksIfNeeded(PageBreakCollection pageBreaks, XmlTextWriter writer, string pageBreakType)
        {
            int count = pageBreaks.Count;
            if (count > 0)
            {
                writer.WriteStartElement(pageBreakType);
                writer.WriteAttributeString("count", count.ToString());
                writer.WriteAttributeString("manualBreakCount", count.ToString());
                foreach (PageBreak @break in pageBreaks)
                {
                    writer.WriteStartElement("brk");
                    writer.WriteAttributeString("id", @break.breakIndex.ToString());
                    writer.WriteAttributeString("min", @break.firstLimit.ToString());
                    writer.WriteAttributeString("max", @break.lastLimit.ToString());
                    writer.WriteAttributeString("man", "1");
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
            }
        }

        private void WritePageMargins(ExcelPrintOptions po, XmlTextWriter writer)
        {
            writer.WriteStartElement("pageMargins");
            writer.WriteAttributeString("left", po.LeftMargin.ToString("G17", CultureInfo.InvariantCulture));
            writer.WriteAttributeString("right", po.RightMargin.ToString("G17", CultureInfo.InvariantCulture));
            writer.WriteAttributeString("top", po.TopMargin.ToString("G17", CultureInfo.InvariantCulture));
            writer.WriteAttributeString("bottom", po.BottomMargin.ToString("G17", CultureInfo.InvariantCulture));
            writer.WriteAttributeString("header", po.HeaderMargin.ToString("G17", CultureInfo.InvariantCulture));
            writer.WriteAttributeString("footer", po.FooterMargin.ToString("G17", CultureInfo.InvariantCulture));
            writer.WriteEndElement();
        }

        private void WritePageSetup(ExcelPrintOptions po, XmlTextWriter writer)
        {
            writer.WriteStartElement("pageSetup");
            if (po.PrintBlackWhite)
            {
                writer.WriteAttributeString("blackAndWhite", "1");
            }
            if (po.DraftQuality)
            {
                writer.WriteAttributeString("draft", "1");
            }
            if (po.UseStartPageNumber)
            {
                writer.WriteAttributeString("useFirstPageNumber", "1");
            }
            if (po.Portrait)
            {
                writer.WriteAttributeString("orientation", "portrait");
            }
            else
            {
                writer.WriteAttributeString("orientation", "landscape");
            }
            if (po.PrintCellNotes)
            {
                if (po.PrintNotesSheetEnd)
                {
                    writer.WriteAttributeString("cellComments", "atEnd");
                }
                else
                {
                    writer.WriteAttributeString("cellComments", "asDisplayed");
                }
            }
            writer.WriteAttributeString("scale", po.AutomaticPageBreakScalingFactor.ToString());
            writer.WriteAttributeString("paperSize", po.PaperSize.ToString());
            writer.WriteAttributeString("firstPageNumber", po.StartPageNumber.ToString());
            writer.WriteAttributeString("fitToWidth", po.FitWorksheetWidthToPages.ToString());
            writer.WriteAttributeString("fitToHeight", po.FitWorksheetHeightToPages.ToString());
            writer.WriteAttributeString("horizontalDpi", po.PrintResolution.ToString());
            writer.WriteAttributeString("verticalDpi", po.VerticalPrintResolution.ToString());
            writer.WriteAttributeString("copies", po.NumberOfCopies.ToString());
            writer.WriteEndElement();
        }

        private void WriteRowColumnToVmlDrawing(XmlTextWriter writer, int index, string elementName)
        {
            writer.WriteStartElement(elementName);
            writer.WriteString(index.ToString());
            writer.WriteEndElement();
        }

        private static void WriteShallowNode(XmlReader reader, XmlWriter writer)
        {
            switch (reader.NodeType)
            {
                case XmlNodeType.Element:
                    writer.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI);
                    writer.WriteAttributes(reader, true);
                    if (!reader.IsEmptyElement)
                    {
                        break;
                    }
                    writer.WriteEndElement();
                    return;

                case XmlNodeType.Attribute:
                case XmlNodeType.Entity:
                case XmlNodeType.Document:
                case XmlNodeType.DocumentFragment:
                case XmlNodeType.Notation:
                case XmlNodeType.EndEntity:
                    break;

                case XmlNodeType.Text:
                    writer.WriteString(reader.Value);
                    return;

                case XmlNodeType.CDATA:
                    writer.WriteCData(reader.Value);
                    return;

                case XmlNodeType.EntityReference:
                    writer.WriteEntityRef(reader.Name);
                    return;

                case XmlNodeType.ProcessingInstruction:
                case XmlNodeType.XmlDeclaration:
                    writer.WriteProcessingInstruction(reader.Name, reader.Value);
                    return;

                case XmlNodeType.Comment:
                    writer.WriteComment(reader.Value);
                    return;

                case XmlNodeType.DocumentType:
                    writer.WriteDocType(reader.Name, reader.GetAttribute("PUBLIC"), reader.GetAttribute("SYSTEM"), reader.Value);
                    return;

                case XmlNodeType.Whitespace:
                case XmlNodeType.SignificantWhitespace:
                    writer.WriteWhitespace(reader.Value);
                    return;

                case XmlNodeType.EndElement:
                    writer.WriteFullEndElement();
                    break;

                default:
                    return;
            }
        }

        private void WriteSharedStrings()
        {
            Stream w = base.builder.CreatePart("/xl/sharedStrings.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml");
            this.sourceParts.Remove("/xl/sharedStrings.xml");
            XmlTextWriter writer = new XmlTextWriter(w, new UTF8Encoding(false));
            try
            {
                writer.WriteStartDocument(true);
                writer.WriteStartElement("sst");
                writer.WriteAttributeString("xmlns", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
                string str = this.strings.Count.ToString();
                writer.WriteAttributeString("count", str);
                writer.WriteAttributeString("uniqueCount", str);
                foreach (string str2 in this.strings)
                {
                    writer.WriteStartElement("si");
                    writer.WriteElementString("t", str2);
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
            }
            finally
            {
                writer.Close();
            }
        }

        private void WriteSheetFormatPr(ExcelWorksheet ws, XmlTextWriter writer)
        {
            writer.WriteStartElement("sheetFormatPr");
            writer.WriteAttributeString("defaultRowHeight", "15");
            if (ws.DefaultColumnWidth != 0x86e)
            {
                writer.WriteAttributeString("defaultColWidth", (((double) ws.DefaultColumnWidth) / 256.0).ToString("G17", CultureInfo.InvariantCulture));
            }
            if (ws.Rows.MaxOutlineLevel > 0)
            {
                writer.WriteAttributeString("outlineLevelRow", ws.Rows.MaxOutlineLevel.ToString());
            }
            if (ws.Columns.MaxOutlineLevel > 0)
            {
                writer.WriteAttributeString("outlineLevelCol", ws.Rows.MaxOutlineLevel.ToString());
            }
            writer.WriteEndElement();
        }

        private void WriteSheetPr(ExcelWorksheet ws, XmlTextWriter writer)
        {
            if ((!ws.ViewOptions.OutlineRowButtonsBelow || !ws.ViewOptions.OutlineColumnButtonsRight) || ws.PrintOptions.FitToPage)
            {
                writer.WriteStartElement("sheetPr");
                writer.WriteStartElement("outlinePr");
                if (!ws.ViewOptions.OutlineRowButtonsBelow)
                {
                    writer.WriteAttributeString("summaryBelow", "0");
                }
                if (!ws.ViewOptions.OutlineColumnButtonsRight)
                {
                    writer.WriteAttributeString("summaryRight", "0");
                }
                writer.WriteEndElement();
                writer.WriteStartElement("pageSetUpPr");
                if (ws.PrintOptions.FitToPage)
                {
                    writer.WriteAttributeString("fitToPage", "1");
                }
                writer.WriteEndElement();
                writer.WriteEndElement();
            }
        }

        private void WriteSheetProtectionIfNeeded(ExcelWorksheet ws, XmlTextWriter writer)
        {
            XlsxSheetPreservationData tag = ws.Tag as XlsxSheetPreservationData;
            if (ws.Protected)
            {
                if ((tag != null) && (tag.SheetProtectionOuterString != null))
                {
                    writer.WriteRaw(tag.SheetProtectionOuterString);
                }
                else
                {
                    writer.WriteStartElement("sheetProtection");
                    writer.WriteAttributeString("sheet", "1");
                    writer.WriteEndElement();
                }
            }
        }

        private static void WriteSheetsCollectionToWorkbook(ExcelWorksheetCollection sheets, string[] rids, XmlTextReader reader, XmlTextWriter writer)
        {
            writer.WriteStartElement("sheets");
            while (reader.Read())
            {
                if ((reader.NodeType == XmlNodeType.EndElement) && (reader.Name == "sheets"))
                {
                    break;
                }
            }
            for (int i = 0; i < rids.Length; i++)
            {
                writer.WriteStartElement("sheet");
                writer.WriteAttributeString("name", sheets[i].Name);
                writer.WriteAttributeString("sheetId", (i + 1).ToString());
                writer.WriteAttributeString("r:id", rids[i]);
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }

        private void WriteStyles()
        {
            Stream w = base.builder.CreatePart("/xl/styles.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml");
            this.sourceParts.Remove("/xl/styles.xml");
            XmlTextWriter writer = new XmlTextWriter(w, new UTF8Encoding(false));
            try
            {
                writer.WriteStartDocument(true);
                writer.WriteStartElement("styleSheet");
                writer.WriteAttributeString("xmlns", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
                this.WriteNumberFormats(writer);
                this.WriteFonts(writer);
                this.WriteFills(writer);
                this.WriteBorders(writer);
                this.WriteCellStyleXfs(writer);
                this.WriteCellXfs(writer);
                this.WriteCellStyles(writer);
                this.WriteDxfsIfNeeded(writer);
                this.WriteTableStyles(writer);
                writer.WriteEndElement();
            }
            finally
            {
                writer.Close();
            }
        }

        private void WriteTableStyles(XmlTextWriter writer)
        {
            writer.WriteStartElement("tableStyles");
            writer.WriteAttributeString("count", "0");
            writer.WriteAttributeString("defaultTableStyle", "TableStyleMedium9");
            writer.WriteAttributeString("defaultPivotStyle", "PivotStyleLight16");
            writer.WriteEndElement();
        }

        private void WriteVmlDrawingCommentBegining(XmlTextWriter writer)
        {
            writer.WriteRaw(this.vmlDrawingBeginingContent);
        }

        private void WriteWorksheet(ExcelWorksheet ws, string partName)
        {
            Stream w = base.builder.CreatePart(partName, "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml");
            SpreadsheetRelationshipCollection relationshipCollection = new SpreadsheetRelationshipCollection();
            XlsxSheetPreservationData tag = ws.Tag as XlsxSheetPreservationData;
            if ((tag != null) && (tag.SourceSheetPath != null))
            {
                relationshipCollection.LoadRels(tag.SourceSheetPath, base.excelFile.preservedXlsx);
            }
            relationshipCollection.Remove("http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing");
            relationshipCollection.Remove("http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing");
            relationshipCollection.Remove("http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments");
            relationshipCollection.Remove("http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink");
            XmlTextWriter writer = new XmlTextWriter(w, new UTF8Encoding(false));
            try
            {
                writer.WriteStartDocument(true);
                writer.WriteStartElement("worksheet");
                writer.WriteAttributeString("xmlns", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
                writer.WriteAttributeString("xmlns:r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
                this.WriteSheetPr(ws, writer);
                this.WriteWorksheetViewSettings(ws, writer);
                this.WriteSheetFormatPr(ws, writer);
                this.WriteColumnInfosIfNeeded(ws, writer);
                this.WriteWorksheetData(ws, writer);
                this.WriteSheetProtectionIfNeeded(ws, writer);
                this.WriteAutoFilterIfNeeded(tag, writer);
                WriteMergedRangesIfNeeded(ws.MergedRanges.Values, writer);
                this.WriteConditionalFormattingIfNeeded(tag, writer);
                this.WriteDataValidationIfNeeded(tag, writer);
                this.WriteHyperlinksIfNeeded(ws.Hyperlinks, writer, relationshipCollection);
                this.WritePageMargins(ws.PrintOptions, writer);
                this.WritePageSetup(ws.PrintOptions, writer);
                this.WriteHeaderFooterIfNeeded(tag, writer);
                this.WritePageBreaksIfNeeded(ws.HorizontalPageBreaks, writer, "rowBreaks");
                this.WritePageBreaksIfNeeded(ws.VerticalPageBreaks, writer, "colBreaks");
                if ((ws.Pictures.Count > 0) || ((tag != null) && (tag.DrawingPath != null)))
                {
                    string target = this.GetFreeFileName("/xl/drawings/", "GemDrawing", "xml");
                    writer.WriteStartElement("drawing");
                    writer.WriteAttributeString("r:id", relationshipCollection.Add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing", target, null));
                    writer.WriteEndElement();
                    this.WriteDrawing(ws, target);
                }
                this.WriteLegacyShapesIfNeeded(ws, relationshipCollection, writer);
                this.WriteLegacyDrawingHFIfNeeded(relationshipCollection, tag, writer);
                writer.WriteEndElement();
                relationshipCollection.SaveRels(partName, base.builder);
                this.sourceParts.Remove(SpreadsheetRelationshipCollection.GetRelationshipPathFromXmlFilePath(partName));
            }
            finally
            {
                writer.Close();
            }
        }

        private void WriteWorksheetData(ExcelWorksheet ws, XmlTextWriter writer)
        {
            writer.WriteStartElement("sheetData");
            int count = ws.Rows.Count;
            for (int i = 0; i < count; i++)
            {
                ExcelRow item = ws.Rows[i];
                ExcelCellCollection allocatedCells = item.AllocatedCells;
                int num3 = allocatedCells.Count;
                writer.WriteStartElement("row");
                writer.WriteAttributeString("r", ExcelRowCollection.RowIndexToName(i));
                if (item.Height != 0xff)
                {
                    writer.WriteAttributeString("ht", (item.Height / 20).ToString());
                    writer.WriteAttributeString("customHeight", "1");
                }
                WriteHiddenOutlineCollapsedIfNeeded(writer, item, ws.ViewOptions, ws.Rows.MaxOutlineLevel);
                for (int j = 0; j < num3; j++)
                {
                    if (allocatedCells[j].HasComment)
                    {
                        CommentShape shape = allocatedCells[j].Comment.Shape;
                        string author = shape.Author;
                        shape.Row = i;
                        shape.Column = j;
                        if (!this.commentAuthorList.Contains(author))
                        {
                            this.commentAuthorList.Add(author);
                        }
                    }
                    if (allocatedCells[j].HasHyperlink)
                    {
                        SpreadsheetHyperlink hyperlink = allocatedCells[j].Hyperlink;
                        hyperlink.Row = i;
                        hyperlink.Column = j;
                    }
                    this.WriteCellIfNeeded(allocatedCells[j], i, j, writer);
                }
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }

        private void WriteWorksheets()
        {
            ExcelWorksheetCollection sheets = base.excelFile.Worksheets;
            int count = sheets.Count;
            string[] rids = new string[count];
            SpreadsheetRelationshipCollection relationships = new SpreadsheetRelationshipCollection();
            relationships.LoadRels("/xl/workbook.xml", base.excelFile.preservedXlsx);
            relationships.Remove("http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet");
            for (int i = 0; i < count; i++)
            {
                string target = "/xl/worksheets/sheet" + (i + 1) + ".xml";
                rids[i] = relationships.Add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet", target, null);
                this.WriteWorksheet(sheets[i], target);
            }
            this.RemoveContentTypeFromTemplate("application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml", true);
            this.RemoveContentTypeFromTemplate("image/", false);
            this.RemoveContentTypeFromTemplate("application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml", true);
            this.RemoveContentTypeFromTemplate("application/vnd.openxmlformats-officedocument.vmlDrawing", true);
            this.RemoveContentTypeFromTemplate("application/vnd.openxmlformats-officedocument.drawing+xml", true);
            this.RemoveContentTypeFromTemplate("application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml", true);
            this.AddToWorkbookXml(sheets, rids);
            if (relationships.GetFirstVisibleOccurrencePath("http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings") == null)
            {
                relationships.Add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings", "/xl/sharedStrings.xml", null);
            }
            relationships.SaveRels("/xl/workbook.xml", base.builder);
            this.sourceParts.Remove(SpreadsheetRelationshipCollection.GetRelationshipPathFromXmlFilePath("/xl/workbook.xml"));
        }

        private void WriteWorksheetViewSettings(ExcelWorksheet ws, XmlTextWriter writer)
        {
            XlsxSheetPreservationData tag = ws.Tag as XlsxSheetPreservationData;
            writer.WriteStartElement("sheetViews");
            writer.WriteStartElement("sheetView");
            if (ws == base.excelFile.Worksheets.ActiveWorksheet)
            {
                writer.WriteAttributeString("tabSelected", "1");
            }
            writer.WriteAttributeString("workbookViewId", "0");
            writer.WriteAttributeString("topLeftCell", CellRange.RowColumnToPosition(ws.ViewOptions.FirstVisibleRow, ws.ViewOptions.FirstVisibleColumn));
            writer.WriteAttributeString("zoomScaleNormal", ws.ViewOptions.Zoom.ToString());
            writer.WriteAttributeString("zoomScaleSheetLayoutView", ws.ViewOptions.PageBreakViewZoom.ToString());
            if (ws.ViewOptions.ShowFormulas)
            {
                writer.WriteAttributeString("showFormulas", "1");
            }
            if (!ws.ViewOptions.ShowGridLines)
            {
                writer.WriteAttributeString("showGridLines", "0");
            }
            if (!ws.ViewOptions.ShowSheetHeaders)
            {
                writer.WriteAttributeString("showRowColHeaders", "0");
            }
            if (!ws.ViewOptions.ShowZeroValues)
            {
                writer.WriteAttributeString("showZeros", "0");
            }
            if (ws.ViewOptions.ShowColumnsFromRightToLeft)
            {
                writer.WriteAttributeString("rightToLeft", "1");
            }
            if (!ws.ViewOptions.ShowOutlineSymbols)
            {
                writer.WriteAttributeString("showOutlineSymbols", "0");
            }
            if (ws.ViewOptions.ShowInPageBreakPreview)
            {
                writer.WriteAttributeString("zoomScale", ws.ViewOptions.PageBreakViewZoom.ToString());
                writer.WriteAttributeString("view", "pageBreakPreview");
            }
            else
            {
                writer.WriteAttributeString("zoomScale", ws.ViewOptions.Zoom.ToString());
                writer.WriteAttributeString("view", "normal");
            }
            if ((tag != null) && (tag.PaneOuterString != null))
            {
                writer.WriteRaw(tag.PaneOuterString);
            }
            writer.WriteEndElement();
            writer.WriteEndElement();
        }
    }
}
